package com.yjd.pub.smsverify.service;

import com.yjd.comm.base.dao.IBaseDao;
import com.yjd.comm.base.enums.DbWREnums;
import com.yjd.comm.base.model.MfqTokenModel;
import com.yjd.comm.base.service.IMfqTokenService;
import com.yjd.comm.base.service.impl.BaseServiceImpl;
import com.yjd.comm.enums.MessageEnum;
import com.yjd.comm.smsverify.model.SmsVerifyModel;
import com.yjd.comm.smsverify.service.ISmsVerifyService;
import com.yjd.comm.system.model.SysParamModel;
import com.yjd.comm.system.util.SysParamUtil;
import com.yjd.comm.util.*;
import com.yjd.comm.vo.Constant;
import com.yjd.comm.vo.SmsTemplate;
import com.yjd.pub.smsverify.dao.ISmsVerifyDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <b>description</b>：短信验证码业务实现<br>
 * <b>time</b>：2017-06-27 08:57:32 <br>
 * <b>author</b>：  yangchangyan@yijiedai.com
 */
@Service("smsVerifyService")
public class SmsVerifyServiceImpl extends BaseServiceImpl implements ISmsVerifyService {

	/**
	 * 插入
	 * 
	 * @param model
	 * @return
	 * @throws Exception
	 */
	public SmsVerifyModel insert(SmsVerifyModel model) throws Exception {
		return this.smsVerifyDao.insertModel(model, true);
	}

	/**
	 * 更新
	 * 
	 * @param model
	 * @return
	 * @throws Exception
	 */
	public int update(SmsVerifyModel model) throws Exception {
		return this.smsVerifyDao.updateModel(model, true);
	}

	/**
	 * 根据id删除
	 * 
	 * @param mobile_number
	 * @return
	 * @throws Exception
	 */
	public int delete(long mobile_number) throws Exception {
		Map<Object, Object> paramMap = new HashMap<Object, Object>();
		paramMap.put("mobile_number", mobile_number);
		return this.smsVerifyDao.deleteModel(paramMap, true);
	}

	/**
	 * 发送短信
	 *
	 * @param mpNumber
	 * @return boolean
	 * @throws Exception
	 */
	@Override
	public int sendMessage(String mpNumber) throws Exception {
		// 是否是数字
		if (StringUtils.isBlank(mpNumber) ||
				!NumberUtils.isNumber(mpNumber)) {
			FrameUtil.throwBaseException1("参数异常");
		}

		Calendar c = Calendar.getInstance();
		int cday = c.get(Calendar.DAY_OF_MONTH); // 当前日期
		Long time = FrameUtil.getTime(c.getTime());

		// 正则匹配
		SysParamModel sysParamModel = SysParamUtil
				.getSysParamModel(Constant.SysParamKeyEnum.REGISTER_REGEX);
		if (sysParamModel != null) {
			Matcher name = Pattern.compile(sysParamModel.getParam_value())
					.matcher(mpNumber);
			if (!name.matches()) {
				FrameUtil.throwBaseException1("手机号格式不正确");
			}
		}

		Long mphoneNumber = Long.valueOf(mpNumber);
		SmsVerifyModel verifySmsModel = this.getModelById(mphoneNumber, DbWREnums.WRITE);
		if (verifySmsModel != null) {
			Long stime = verifySmsModel.getSent_time();
			if (stime == null) {
				FrameUtil.throwBaseException1("业务短信表发送时间异常");
			}
			Date sdate = DateUtil.timestampToDate1(stime);
			if (sdate == null) {
				FrameUtil.throwBaseException1("业务短信表发送时间异常");
			}
			//获得发送短信的日期
			Calendar sCal = Calendar.getInstance();
			sCal.setTime(sdate);
			int sday = sCal.get(Calendar.DAY_OF_MONTH);

			int num = verifySmsModel.getNum();

			//60秒以内只能连续发送一次
			if((time - stime) <= 5){
				return MessageEnum.SendStatus.frequency.getCode();
			}

			// 如果不是同一天
			if (sday != cday) {
				this.delete(mphoneNumber);
			} else if (num >= 10) {
				return MessageEnum.SendStatus.max.getCode();
			}

			//一小时内发送短信不能超过三次
			if(MsgHourCountUtils.validate(mpNumber,time)){
				return MessageEnum.SendStatus.hourmax.getCode();
			}


		}

		// 获取短信相关参数
		sysParamModel = SysParamUtil
				.getSysParamModel(Constant.SysParamKeyEnum.MSG_CODE_VALID_TIME);
		if (sysParamModel == null) {
			FrameUtil.throwBaseException1("系统参数表异常,没有找到短信有效期");
		}

		String times = sysParamModel.getParam_value();
		if (StringUtils.isBlank(times)) {
			FrameUtil.throwBaseException1("系统参数表异常,短信有效期为空");
		}

		if (!NumberUtils.isNumber(times)) {
			FrameUtil.throwBaseException1("系统参数表异常,短信有效期不是数字");
		}

		verifySmsModel = this.getModelById(mphoneNumber , DbWREnums.WRITE);
		String code = SecurityCode.getRandomNumber(6);
		if (verifySmsModel != null) {
			verifySmsModel.setSmscode(code);
			verifySmsModel.setNum(1);
			verifySmsModel.setSent_time(FrameUtil.getTime(null));//更新最新发送时间
			if(this.update(verifySmsModel) != 1){
				FrameUtil.throwBaseException1("更新验证码记录异常");
			}
		} else {
			verifySmsModel = new SmsVerifyModel();
			verifySmsModel.setMobile_number(mphoneNumber);
			verifySmsModel.setSmscode(code);
			verifySmsModel.setSent_time(FrameUtil.getTime(null));//更新最新发送时间
			if(this.insert(verifySmsModel) == null){
				FrameUtil.throwBaseException1("插入验证码记录异常");
			}
		}

		String rcode = SmsSenderUtils.smsSend(mpNumber,SmsTemplate.getSmsTemplateMsg(SmsTemplate.SMS_PASSWORD_REGAIN,code,times),"");

		if (!"0".equals(rcode)) {
			FrameUtil.throwBaseException1("发送短信异常");
		}else {
           //发送成功则记录验证次数为0
			String keys = "DXYZ"+mphoneNumber;
		  MfqTokenModel mfqTokenModel =  mfqTokenService.getModelById(keys,DbWREnums.WRITE);
			if(mfqTokenModel==null){
				mfqTokenModel = new MfqTokenModel();
				mfqTokenModel.setToken_key(keys);
				mfqTokenModel.setToken_value("1");
				mfqTokenService.insert(mfqTokenModel);
			}else {
				mfqTokenModel.setToken_value("1");
				mfqTokenService.update(mfqTokenModel);
			}
		}

		return MessageEnum.SendStatus.success.getCode();

	}

    /**
     * 比较短信
     *
     * @param mobile
     * @param code
     * @param msgCount
     * @param max      @return boolean
     * @throws Exception
     */
    @Override
    public int compareMessageCode(String mobile, String code, int msgCount, int max) throws Exception {
		String keys = "DXYZ"+mobile;

		if (StringUtils.isBlank(mobile) || StringUtils.isBlank(code)
                || !NumberUtils.isNumber(mobile)) {
            FrameUtil.throwBaseException1("参数异常");
        }

        // 正则匹配
        SysParamModel sysParamModel = SysParamUtil
                .getSysParamModel(Constant.SysParamKeyEnum.REGISTER_REGEX);
        if (sysParamModel != null) {
            Matcher name = Pattern.compile(sysParamModel.getParam_value())
                    .matcher(mobile);
            if (!name.matches()) {
                FrameUtil.throwBaseException1("手机号格式不正确");
            }
        }

        SmsVerifyModel verifySmsModel = this.getModelById(mobile, DbWREnums.WRITE);
        if (verifySmsModel == null) {
            return MessageEnum.ValidStatus.nullity.getCode();
        }

        String dbMsgCode = verifySmsModel.getSmscode();
        if(StringUtils.isBlank(dbMsgCode)|| dbMsgCode.equals("0")){
            return MessageEnum.ValidStatus.nullity.getCode();
        }

        //验证次数大于最大次数
        if (msgCount > max) {
            verifySmsModel.setSmscode("0");
            verifySmsModel.setNum(null);
            if(this.update(verifySmsModel) != 1){
                FrameUtil.throwBaseException1("更新短信记录表异常");
            }
			mfqTokenService.delete(keys);//删掉验证次数
            return MessageEnum.ValidStatus.max.getCode();
        }

        sysParamModel = SysParamUtil
                .getSysParamModel(Constant.SysParamKeyEnum.MSG_CODE_VALID_TIME);
        if (sysParamModel == null) {
            FrameUtil.throwBaseException1("系统参数表异常,没有找到短信有效期");
        }

        String times = sysParamModel.getParam_value();
        if (StringUtils.isBlank(times)) {
            FrameUtil.throwBaseException1("系统参数表异常,短信有效期为空");
        }

        if (!NumberUtils.isNumber(times)) {
            FrameUtil.throwBaseException1("系统参数表异常,短信有效期不是数字");
        }

        int time = Integer.parseInt(times);

        Calendar c = Calendar.getInstance();
        c.add(Calendar.MINUTE, -time);
        Long ctime = FrameUtil.getTime(c.getTime());
        Long smstime = verifySmsModel.getSent_time();

        if (verifySmsModel.getSmscode().equals(code)) {
			mfqTokenService.delete(keys);//删掉验证次数

			verifySmsModel.setSmscode("0");
            verifySmsModel.setNum(null);
			if(this.update(verifySmsModel) != 1){
                FrameUtil.throwBaseException1("更新短信记录表异常");
            }
            if (ctime <= smstime) {
                return MessageEnum.ValidStatus.success.getCode();
            }
        }else{
			MfqTokenModel mfqTokenModel =  mfqTokenService.getModelById(keys,DbWREnums.WRITE);
			if(mfqTokenModel==null){
				mfqTokenModel = new MfqTokenModel();
				mfqTokenModel.setToken_key(keys);
				mfqTokenModel.setToken_value("2");
				mfqTokenService.insert(mfqTokenModel);
			}else {
				Integer count =  Integer.parseInt(mfqTokenModel.getToken_value())+1;
				mfqTokenModel.setToken_value(count+"");
				mfqTokenService.update(mfqTokenModel);
			}
		}
        return MessageEnum.ValidStatus.mismatching.getCode();
    }

    @Resource
	private ISmsVerifyDao smsVerifyDao;

	@Resource
	private IMfqTokenService mfqTokenService;

	@Override
	public IBaseDao getBaseDao() {
		return this.smsVerifyDao;
	}

}
